package tpcomp2010.estructura;

/**
 * Clase nodo, representa a los estados en el automata
 * implementa Comparable<?>
 */
public class Nodo implements Comparable<Nodo> {

    /**
     * identificador del nodo
     */
    private int id;

    /**
     * lista de aristas que posee el nodo
     * @see ListaAristas
     */
    private ListaAristas aristas;

    /**
     * establece si es un nodo inicial
     */
    private boolean nodoInicial;

    /**
     * establece si es un nodo final
     */
    private boolean nodoFinal;

    /**
     * establece si el nodo ya fue visitado
     */
    private boolean visitado;

    /**
     * Class Constructor especificando el id, si es un nodo incial, si es final
     * y si ya fue visitado
     * @param id identificador del nodo
     * @param esInicial establece si el nodo es inicial
     * @param esFinal establece si el nodo es final
     * @param visitado establece si el nodo ya fue visitado
     */
    public Nodo(int id, boolean esInicial, boolean esFinal, boolean visitado) {
        this.id = id;
        this.nodoInicial = esInicial;
        this.nodoFinal = esFinal;
        this.visitado = visitado;
        this.aristas = new ListaAristas();
    }

    /**
     * Retorna el id del nodo
     * @return identidifacor del nodo
     */
    public int getId() {
        return id;
    }

    /**
     * Retorna la lista de aristas que posee el nodo
     * @return Lista aristas del nodo
     */
    public ListaAristas getAristas() {
        return aristas;
    }

    /**
     * Verifica si el nodo es final
     * @return true si el nodo es final, false en caso contrario
     */
    public boolean isNodofinal() {
        return nodoFinal;
    }

    /**
     * Verifica si el nodo es inicial
     * @return true si el nodo es inicial, false en caso contrario
     */
    public boolean isNodoinicial() {
        return nodoInicial;
    }

    /**
     * Verifica si el nodo ya fue visitado
     * @return true si el nodo ya fue visitado, false en caso contrario
     */
    public boolean isVisitado() {
        return visitado;
    }

    /**
     * Establece el valor ID del nodo
     * @param id identificador del nodo
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * Establece si el nodo el final
     * @param estadofinal
     */
    public void setNodofinal(boolean estadofinal) {
        this.nodoFinal = estadofinal;
    }

    /**
     * Establece si el nodo el inicial
     * @param estadoinicial 
     */
    public void setNodoinicial(boolean estadoinicial) {
        this.nodoInicial = estadoinicial;
    }

    /**
     * Establece si el nodo fue visitado
     * @param visitado 
     */
    public void setVisitado(boolean visitado) {
        this.visitado = visitado;
    }

    /**
     * Agrega una arista a la lista de aristas del nodo
     * @param e Arista a agregar
     */
    public void agregarArista(Arista e) {
        // Insertar en la lista de aristas para tener un método eficiente de
        // recorrido en el futuro
        aristas.insertar(e);
    }

    /**
     * DAdo un Token, verifica si el objeto actual contiene una arista con
     * dicho token, y devuelve el nodo destino de esa arista
     * @param a el Token
     * @return el Nodo destino de la arista, null en caso de que no exista
     */
    public Nodo nodoDestino(Token a) {
        return nodoDestinoString(a.getValor());
    }

    /**
     * DAdo una cadena, verifica si el objeto actual contiene una arista con
     * dicha cadena, y devuelve el nodo destino de esa arista
     * @param a cadena que representa el token
     * @return el Nodo destino de la arista, null en caso de que no exista
     */
    public Nodo nodoDestinoString(String a) {
        for (Arista x : aristas) {
            if (x.getEtiqueta().compareTo(a) == 0) {
                return x.getNodoDestino();
            }
        }
        return null;
    }

    /**
     * @see Nodo.nodoDestino(Token a)
     */
    public Nodo getDestino(String simbolo) {
        Arista link = this.getSimboloArista(simbolo);
        Nodo result = null;

        if (link != null) {
            result = link.getNodoDestino();
        }
        return result;
    }

    /**
     * DEvuelve la arista que contiene el simbolo dado
     * @param simbolo
     * @return arista que contiene el simbolo
     */
    public Arista getSimboloArista(String simbolo) {
        return this.aristas.getSimboloArista(simbolo);
    }

    /**
     * Compara el id del nodo con el id de otro Nodo
     * @param e el nodo a comparar
     * @return -1 en caso de que el id de e sea mayor, 1 en el caso de que el id
     * de e sea menor y 0 en caso de que sean iguales.
     */
    public int compareTo(Nodo e) {
        if (this.getId() == e.getId()) {
            return 0;
        } else if (this.getId() > e.getId()) {
            return 1;
        } else {
            return -1;
        }
    }

    /**
     * Convierte el nodo en una cadeca.
     * @return cadena formateada del nodo
     */
    @Override
    public String toString() {
        String result = "" + id;
        if (this.isNodofinal()) {
            result = result + "(fin)";
        }

        if (this.isNodoinicial()) {
            result = result + "(ini)";
        }
        return result;
    }
}
